package com.aloda.aop;

import com.alibaba.fastjson.JSONObject;
import com.aloda.constant.ClassConstant;
import com.aloda.constant.LogConstant;
import com.aloda.constant.MethodConstant;
import com.aloda.context.BaseContext;
import com.aloda.entity.Employee;
import com.aloda.entity.OperationLog;
import com.aloda.mapper.EmpMapper;
import com.aloda.mapper.OperationLogMapper;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.Objects;

/**
 * 为controller层自动记录操作日志
 */
@Component
@Aspect //切面类
@Slf4j
public class OpLogAspect {

    @Autowired
    private EmpMapper empMapper;
    @Autowired
    private OperationLogMapper operationLogMapper;

    @Around("@annotation(com.aloda.anno.OpLog)")
    public Object operationLog(ProceedingJoinPoint joinPoint) throws Throwable {

        log.info("开始进行相关操作日志自动记录...");

        //先获取当前操作者用户名
        Long userId =BaseContext.getCurrentId();
        String username = empMapper.getEmpUsernameById(userId);

        //获取操作数据
        LocalDateTime time = LocalDateTime.now();

        //获取操作类名
        String className = joinPoint.getTarget().getClass().getName();
        String shortClassName = className.substring(className.lastIndexOf(".")+1);

        //获取操作的方法名
        String methodName = joinPoint.getSignature().getName();

        //操作方法的参数
        Object[] args = joinPoint.getArgs();
        String methodParams = Arrays.toString(args);

        long begin = System.currentTimeMillis();

        //调用原始目标方法运行
        Object result = joinPoint.proceed();

        long end = System.currentTimeMillis();

        //方法返回值
        String returnValue = JSONObject.toJSONString(result);

        //操作耗时
        long costTime=end-begin;

        //操作的描述
        String description = username+getDescription(shortClassName,methodName);

        OperationLog operationLog = OperationLog.builder()
                .userId(userId)
                .username(username)
                .description(description)
                .time(time)
                .className(className)
                .methodName(methodName)
                .methodParams(methodParams)
                .returnValue(returnValue)
                .costTime(costTime)
                .build();


        if(shortClassName.equals(ClassConstant.EMP)){
            operationLog.setSort(LogConstant.EMP_LOG);
        }
        if (shortClassName.equals(ClassConstant.USER)) {
            operationLog.setSort(LogConstant.USER_LOG);
        }

        operationLogMapper.insert(operationLog);

        log.info("aop记录操作日志：{}",operationLog);
        return result;
    }

    /**
     * 获取操作的简单描述
     * @param methodName
     * @return
     */
    private String getDescription(String shortClassName,String methodName){
        String description="其它操作";
        if(Objects.equals(shortClassName, ClassConstant.EMP)) {
            switch (methodName) {
                case MethodConstant.add -> description = "新增员工";
                case MethodConstant.update -> description = "编辑员工";
                case MethodConstant.resetPwd -> description = "进行了重置密码";
                case MethodConstant.status -> description = "进行了状态设置";
                case MethodConstant.logout -> description = "进行了权限相关操作";
            }
        }else if(Objects.equals(shortClassName, ClassConstant.USER)){
            switch (methodName) {
                case MethodConstant.user_add -> description = "新增用户";
                case MethodConstant.user_edit -> description = "编辑用户";
                case MethodConstant.user_logout -> description = "进行了权限相关操作";
            }
        }
        return description;
    }
}
